iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
自我挑戰組

30天從零到有,帶你進入程式的世界系列 第 27

[Day 27] Ruby: 封裝、繼承、多型

  • 分享至 

  • xImage
  •  

1. 封裝(Encapsulation)

指的是將一個物件的狀態(屬性或資料)和行為(方法或函式)包裝在一個單一的單位中,並且限制外部程式碼對這個單位內部的直接訪問。封裝的目標是隱藏物件的內部實現細節,同時提供一個公共介面供其他程式碼與之互動。
簡單才說就是把內部的實作內容隱藏起來,讓使用者只需要知道怎麼呼叫這個方法即可。

  1. 屬性和方法的組合

    • 封裝通常涉及將物件的屬性(或成員變數)和方法(或函式)組合在一個類別(或物件)中。
    • 屬性表示物件的狀態,方法則定義了可以對物件執行的操作。
  2. 資料隱藏

    • 透過封裝,物件的內部資料可以被隱藏起來,並且只能透過公共方法來訪問或修改這些資料。
    • 這種隱藏允許物件維護自身的一致性和完整性,同時防止外部程式碼不當地修改內部狀態。
  3. 公共方法

    • 封裝定義了物件的公共方法,這是外部程式碼可以使用的方法集合。
    • 這些公共方法提供了一個標準的方式來與物件互動,從而隱藏了內部實現細節。
  4. 訪問控制

    • 封裝允許定義訪問控制,以確保只有特定的方法可以訪問或修改特定的屬性。
    • 可以使用「getter」和「setter」方法來控制屬性的訪問。
    • 使用public , private , protected 控制訪問權
    1. public 方法:
      • public 方法是默認的訪問層級,不需要額外的關鍵字聲明。
      • 這些方法可以從類的外部和內部訪問,也就是說,它們可以被任何程式碼調用。
      • 一個類的公開方法通常用於提供對該類的功能的外部訪問。
    2. private 方法:
      • 使用 private 關鍵字聲明的方法只能在類的內部使用,外部程式碼無法訪問它們。
      • 通常,這些方法用於實現內部細節,不希望外部程式碼直接調用它們。
      • private 方法可以通過實例內部訪問,但不能在外部進行直接調用。
    3. protected 方法:
      • 使用 protected 關鍵字聲明的方法在類的內部和子類中可以訪問,但在類的外部不能被訪問。
      • protected 方法通常用於實現一些只允許特定程式碼訪問的行為,但不希望公開成為公共接口。
      • 子類可以訪問父類的 protected 方法,這使得繼承關係中的一些特定行為得以實現。
class MyClass
  def public_method
    puts "This is a public method"
  end

  private

  def private_method
    puts "This is a private method"
  end

  protected

  def protected_method
    puts "This is a protected method"
  end
end

class MySubClass < MyClass
  def access_methods
    public_method            # 可以訪問父類別的公開方法
    protected_method         # 可以訪問父類別的受保護方法
    # private_method         # 不能訪問父類別的私有方法,這會引發錯誤
  end
end

obj = MyClass.new
obj.public_method            # 可以從外部訪問公開方法
# obj.protected_method       # 不能從外部訪問受保護方法,這會引發錯誤
# obj.private_method         # 不能從外部訪問私有方法,這會引發錯誤

sub_obj = MySubClass.new
sub_obj.access_methods       # 子類可以訪問父類的公開和受保護方法

2. 繼承(Inheritance)

允許一個類別(子類別)繼承另一個類別(父類別)的屬性和方法。這個概念有助於建立層次結構的類別,促使代碼重用和結構化。

  1. 父類別(超類別)和子類別(衍生類別)
    • 在繼承中,有一個父類別(或超類別),它是被繼承的類別,並且一個或多個子類別(或衍生類別),它們是繼承父類別的類別。
    • 父類別定義了一個通用的行為和屬性,而子類別可以繼承這些行為和屬性,同時還可以擴展或覆寫它們。
  2. 繼承的優點
    • 代碼重用:繼承允許子類別使用父類別的代碼,從而減少重複性的程式碼,提高了代碼的可維護性。
    • 結構化:繼承幫助我們建立類別之間的層次結構,使程式碼更有結構,更容易理解。
  3. 如何實現繼承
    • 在 Ruby 中,使用 < 符號來建立繼承關係。子類別可以通過繼承父類別來獲得父類別的方法和屬性。
    • 子類別可以覆寫(override)父類別的方法,以提供自己的實現。當子類別調用相同名稱的方法時,將使用子類別的實現。
  4. super 關鍵字
    • 子類別在覆寫父類別的方法時,可以使用 super 關鍵字來調用父類別的同名方法。這允許在子類別中擴展父類別的行為而不完全覆寫它。
class Animal
  def speak
    "Some sound"
  end
end

class Dog < Animal
  def speak
    "Woof!"
  end
end

class Cat < Animal
  def speak
    "Meow!"
  end
end

Animal 是父類別,DogCat 是子類別。它們都繼承了 Animalspeak 方法,但覆寫了它以提供不同的實現。當我們創建 DogCat 的實例並呼叫 speak 方法時,將分別返回 "Woof!" 和 "Meow!"。

3. 多型(Polymorphism):

它允許不同類別的物件對相同的消息(方法)做出不同的回應。這樣的概念使我們可以使用通用的介面來操作不同類型的物件,使程式碼更具靈活性和可擴展性。在 Ruby 中,多型通常實現為方法名稱相同,但不同類別的物件具有不同的實現。

抽象類別(Abstract Class)是實現多型的一種方式,雖然 Ruby 沒有嚴格的抽象類別機制,但我們可以透過特定的方式來實現類似的功能。

  1. 多型的實現
    • 多型的實現基於方法重寫(Method Overriding)的概念。不同的子類別可以覆寫父類別中的方法,以提供自己的實現。
    • 要實現多型,首先需要有一個通用的介面或超類別(父類別),其中包含了一個或多個方法的聲明,但不提供實際的實現。
    • 子類別(衍生類別)應該繼承這個超類別,然後根據自己的需求覆寫父類別的方法。
  2. 抽象類別的實現
    • 在 Ruby 中,抽象類別通常是通過約定和註釋來實現的,而不是語言本身提供的一個內建功能。
    • 通常,我們會在父類別中定義一個虛擬方法(也可以稱為抽象方法),但不提供實際的實現。這個方法僅僅是一個方法聲明,用來告訴子類別必須實作它。
    • 如果子類別沒有實作這個虛擬方法,則通常會引發異常或錯誤,這迫使子類別實作該方法。
class Animal
  def speak
    raise NotImplementedError, "子類別必須實作這個方法"
  end
end

class Cat < Animal
  def speak
    "Meow!"
  end
end

class Dog < Animal
  def speak
    "Woof!"
  end
end

Animal 是一個抽象類別,它定義了一個虛擬的 speak 方法。CatDog 子類別都繼承了 Animal,並覆寫了 speak 方法以提供自己的實現。如果有其他子類別未實作 speak 方法,則會引發 NotImplementedError


上一篇
[Day 26] Ruby: 模組
下一篇
[Day 28] Rails : 簡易部落格 1
系列文
30天從零到有,帶你進入程式的世界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言